package com.warm.jpa.service.impl;

import com.warm.jpa.entity.BaseUserEntity;
import com.warm.jpa.repository.BaseUserRepository;
import com.warm.jpa.service.BaseUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * @Date: 2019/12/5 9:42
 * @Author: LChuang
 * @Description:
 */
@Service
public class BaseUserServiceImpl implements BaseUserService {

    @Autowired
    BaseUserRepository baseUserRepository;

    @Override
    public Page<BaseUserEntity> findBySpec(int pageNum, int size) {
        String name = "warm";
        Integer age = 20;
        // 定义分页大小
        Pageable pageable = PageRequest.of(pageNum, size);

        // findAll(Specification, Pageable);
        Page<BaseUserEntity> page = baseUserRepository.findAll(new Specification<BaseUserEntity>() {
            // 主要围绕 toPredicate(root, criteriaQuery, criteriaBuilder) 方法

            /**
             * root : 要查询的对象，也就是实体类型，实体类型好比sql语句中的from后的表
             * criteriaQuery : Specific的顶层查询对象，它包含查询的各个部分：select, from, where, group by, order by
             * criteriaBuilder : 用来构建CriteriaQuery的构建器对象Predicate(谓语)  gt, ge, lt, le, between, like
             * Predicate : 就是多条件查询中的条件
             */
            @Override
            public Predicate toPredicate(Root<BaseUserEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<>();
                if(name != ""){
                    Predicate likeP = criteriaBuilder.like(root.get("name"), "%" + name + "%");
                    list.add(likeP);
                }
                if(age != null){
                    Predicate betweenP = criteriaBuilder.between(root.get("age"), 10, 21);
                    list.add(betweenP);
                }
                criteriaQuery.orderBy(criteriaBuilder.asc(root.get("id")));

                Predicate[] predicates = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(predicates));
            }
        }, pageable);

        return page;
    }
}
